/*
 * RunPipeline.java
 *
 * Created on September 2, 2006, 1:22 PM
 *
 * (C) 2006 R. Alexander Milowski
 */

package com.smallx.xproc.tools;

import com.smallx.xproc.ModelErrorException;
import com.smallx.xproc.PipelineModel;
import com.smallx.xproc.PipelineModelBuilder;
import com.smallx.xproc.compiler.FlowGraph;
import com.smallx.xproc.compiler.graph.GraphML;
import com.smallx.xproc.compiler.graph.Lattice;
import edu.uci.ics.jung.graph.ArchetypeEdge;
import edu.uci.ics.jung.graph.ArchetypeVertex;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.decorators.ConstantEdgeFontFunction;
import edu.uci.ics.jung.graph.decorators.ConstantEdgeValue;
import edu.uci.ics.jung.graph.decorators.EdgeStringer;
import edu.uci.ics.jung.graph.decorators.VertexStringer;
import edu.uci.ics.jung.io.GraphMLFile;
import edu.uci.ics.jung.visualization.FRLayout;
import edu.uci.ics.jung.visualization.PluggableRenderer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import java.awt.Font;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JFrame;
import org.infoset.xml.Document;
import org.infoset.xml.DocumentLoader;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.XMLException;
import org.infoset.xml.sax.SAXDocumentLoader;
import org.infoset.xml.util.WriterItemDestination;

/**
 *
 * @author alex
 */
public class GenerateFlowGraph extends CommandLine {
   
   final static String VIEW_OPTION = "view";
   final static String GRAPH_INPUT_OPTION = "g";
   /** Creates a new instance of RunPipeline */
   public GenerateFlowGraph() {
   }
   
   protected void usage() {
      System.err.println(this.getClass().getName()+" pipeline");
   }
   
   protected void setup() {
      setMinimumArguments(1);
      allowOption(VIEW_OPTION);
      allowOption(GRAPH_INPUT_OPTION);
   }
   
   protected ItemDestination getOutput()
   throws IOException,XMLException {
      Writer out = new OutputStreamWriter(System.out,"UTF-8");
      return new WriterItemDestination(out,"UTF-8");
   }
   
   protected void viewGraph(Reader input) {
      GraphMLFile gfile = new GraphMLFile();
      Graph g = gfile.load(input);

      PluggableRenderer pr = new PluggableRenderer();
      VisualizationViewer vv = new VisualizationViewer(new FRLayout(g), pr);

      EdgeStringer edgeStringer = new EdgeStringer(){
         public String getLabel(ArchetypeEdge e) {
            return e.getUserDatum("label").toString();
         }
      };
      pr.setEdgeStringer(edgeStringer);
      VertexStringer vertexStringer = new VertexStringer() {
         public String getLabel(ArchetypeVertex v) {
            return v.getUserDatum("label").toString();
         }
      };
      pr.setVertexStringer(vertexStringer);
      pr.setEdgeLabelClosenessFunction(new ConstantEdgeValue(0.4));
      pr.setEdgeFontFunction(new ConstantEdgeFontFunction(Font.decode("Arial--10")));
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.getContentPane().add(vv);
      f.pack();
      f.setVisible(true);
      
   }
   
   protected int runProgram() {
      String [] args = getArguments();
      try {
         if (hasOption(GRAPH_INPUT_OPTION) && !hasOption(VIEW_OPTION)) {
            reportError("The -"+GRAPH_INPUT_OPTION+" requires the -"+VIEW_OPTION+" option.");
            return 1;
         }
         Lattice lattice = null;
         if (!hasOption(GRAPH_INPUT_OPTION)) {
            URI pipeLocation = toURI(args[0]);

            DocumentLoader loader = new SAXDocumentLoader();
            Document doc = loader.load(pipeLocation);
            PipelineModelBuilder builder = new PipelineModelBuilder();
            PipelineModel model = builder.build(doc);
            model.resolve();

            FlowGraph graph = new FlowGraph(model);

            graph.compile();
            graph.analyze();

            lattice = graph.getLattice();
         }
         
         if (hasOption(VIEW_OPTION)) {
            if (hasOption(GRAPH_INPUT_OPTION)) {
               viewGraph(new FileReader(args[0]));
            } else {
               GraphML graphml = new GraphML();
               StringWriter out = new StringWriter();
               graphml.generate(lattice,new WriterItemDestination(out,"UTF-8"));

               viewGraph(new StringReader(out.toString()));
            }
            return -1;
         } else {
            GraphML graphml = new GraphML();
            graphml.generate(lattice,getOutput());
            return 0;
         }
         
      } catch (ModelErrorException ex) {
         ex.printStackTrace();
      } catch (XMLException ex) {
         ex.printStackTrace();
      } catch (IOException ex) {
         ex.printStackTrace();
      } catch (URISyntaxException ex) {
         ex.printStackTrace();
      }
      return 1;
   }
   
   public static void main(String [] args) {
      GenerateFlowGraph cmd = new GenerateFlowGraph();
      if (cmd.parseArguments(args)) {
         cmd.run();
         if (cmd.getStatusCode()>=0) {
            System.exit(cmd.getStatusCode());
         }
      } else {
         System.exit(1);
      }
   }
   
}
